import { _decorator, Component, Node, Sprite, SpriteFrame, director, game, Label, assetManager, resources, Vec3, instantiate, Prefab, AssetManager, random, randomRange } from 'cc';
import { plant_base } from './plant_base';

const { ccclass, property } = _decorator;

@ccclass('MainManager')
export class MainManager extends Component {
    private static _instance: MainManager = null;
    public static getInstance(): MainManager {
        return this._instance;
    }

    protected onLoad(): void {
        if (MainManager._instance === null) {
            MainManager._instance = this;
        }
    }

    start() {
        // 初始化游戏
        this.initGame();
    }

    update(deltaTime: number) {

    }

    private async initGame(): Promise<void> {
        try {
            // 加载背景资源
            const backgroundSprite = await this.loadDir();
            // 生成地图
            this.generateMap(backgroundSprite[0]);
            console.log('游戏初始化完成');
            this.loadFlower();
            console.log('游戏初始化完成2222');

             this.scheduleOnce(() => {
                console.log('游戏初始化完成3333');
                 this.loadFlower();
            }, 5);
        } catch (error) {
            console.error('游戏初始化失败:', error);
        }
    }

    /**
     * 加载远程bundle并获取其中的预制体
     * 正确的远程bundle加载流程：先加载bundle，然后通过bundle对象加载其中的资源
     */
    /**
     * 加载远程bundle并获取其中的预制体（使用async/await方式）
     */
    private async loadRemoteBundleAndPrefabs() {
        const bundleUrl = 'http://127.0.0.1/remote/testPrefab'; // 远程bundle的URL
        const bundleName = 'sun_flower'; // bundle名称
        console.log(`开始加载远程bundle: ${bundleUrl}`);
        
        try {
            // 判断当前的bundle是否存在
            let bundle = assetManager.bundles[bundleName];
            
            // 如果bundle不存在，则加载远程bundle
            if (!bundle) {
                try {
                    bundle = await new Promise<AssetManager.Bundle>((resolve, reject) => {
                        assetManager.loadBundle(bundleUrl, {version: '52a7e'},(err, loadedBundle) => {
                            if (err) {
                                console.warn(`远程bundle加载失败(1): ${err.message}`);
                                // 尝试不带版本号加载
                                assetManager.loadBundle(bundleUrl, (err2, loadedBundle2) => {
                                    if (err2) {
                                        reject(err2);
                                    } else {
                                        resolve(loadedBundle2);
                                    }
                                });
                            } else {
                                resolve(loadedBundle);
                            }
                        });
                    });
                    
                    console.log(`远程bundle加载成功: ${bundle.name}`);
                } catch (error) {
                    console.error(`远程bundle加载失败: ${error.message}`);
                    console.log('尝试使用本地预制体作为备用方案');
                    // 远程加载失败，使用本地预制体
                    await this.loadLocalPrefab(bundleName);
                    return; // 结束当前方法，因为已经通过备用方案加载了预制体
                }
            } else {
                console.log('bundle已存在，直接使用');
            }
            
            // 加载预制体（使用await方式）
            await this.loadPrefabFromBundle(bundle, bundleName);
            
        } catch (error) {
            console.error(`加载远程bundle或预制体失败: ${error.message}`);
            // 远程加载失败，尝试使用本地预制体
            try {
                console.log('尝试使用本地预制体作为备用方案');
                await this.loadLocalPrefab(bundleName);
            } catch (localError) {
                console.error(`本地预制体加载也失败: ${localError.message}`);
            }
        }
    }
    
    /**
     * 加载本地预制体作为远程加载失败的备用方案
     */
    private async loadLocalPrefab(prefabName: string): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            // 使用assetManager.loadAny加载本地prefabs目录下的预制体
            // 注意：这里假设预制体在assets/prefabs/目录下
            assetManager.loadAny({
                uuid: '', // 如果知道uuid可以直接填写
                path: `prefabs/${prefabName}`, // 相对路径
                type: Prefab
            }, (err, prefab) => {
                if (err) {
                    console.error(`加载本地预制体 ${prefabName} 失败: ${err.message}`);
                    // 如果assetManager.loadAny失败，尝试直接从prefabs目录加载
                    resources.load(`../prefabs/${prefabName}`, Prefab, (err2, prefab2) => {
                        if (err2) {
                            reject(err2);
                        } else {
                            this.instantiatePrefab(prefab2, prefabName);
                            resolve();
                        }
                    });
                } else {
                    console.log(`本地预制体 ${prefabName} 加载成功`);
                    this.instantiatePrefab(prefab as Prefab, prefabName);
                    resolve();
                }
            });
        });
    }
    
    /**
     * 从已加载的bundle中加载单个预制体（使用async/await方式）
     */
    private async loadPrefabFromBundle(bundle: AssetManager.Bundle, prefabName: string): Promise<void> {
        console.log(`从bundle中加载预制体: ${prefabName}`);
        
        try {
            // 使用Promise方式调用bundle.load，并await结果
            const prefab = await new Promise<Prefab>((resolve, reject) => {
                bundle.load(prefabName, Prefab, (err, loadedPrefab) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(loadedPrefab);
                    }
                });
            });
            
            console.log(`预制体 ${prefabName} 加载成功`);
            this.instantiatePrefab(prefab, prefabName);
            
        } catch (error) {
            console.error(`加载预制体 ${prefabName} 失败: ${error.message}`);
            throw error; // 向上层抛出错误，以便调用者可以处理
        }
    }
    
    private instantiatePrefab(prefab: Prefab, prefabName: string) {
        try {
            // 实例化预制体
            const instance = instantiate(prefab);
            
            // 设置实例化节点的名称
            instance.name = prefabName;
            
            // 设置实例化节点的父节点
            instance.parent = this.node;
            let plants = instance.getComponent(plant_base);
            console.log('------------', plants);
            // 设置位置（可以根据需要调整）
            instance.setPosition(randomRange(-200, 200), 0, 0);
            
            console.log(`预制体 ${prefabName} 实例化完成`);
        } catch (error) {
            console.error(`实例化预制体 ${prefabName} 失败: ${error.message}`);
        }
    }
    
    // 保留原有的loadFlower方法，但修改为调用正确的远程bundle加载方法
    private loadFlower() {
        console.log('开始加载向日葵预制体');
        // 调用正确的远程bundle加载方法
         this.loadRemoteBundleAndPrefabs();
    }

    loadDir(): Promise<SpriteFrame[]> {
        return new Promise((resolve, reject) => {
            // Load all sprite frames in the bg1 directory
            resources.loadDir('images/bg1', SpriteFrame, (err, assets: SpriteFrame[]) => {
                if (err) {
                    console.error('加载背景资源目录失败:', err);
                    reject(err);
                    return;
                }
                
                console.log('背景资源目录加载完成，找到', assets.length, '个精灵帧');
                
                // 安全检查：确保至少有一个精灵帧
                if (assets && assets.length > 0) {
                    resolve(assets);
                } else {
                    const error = new Error('背景资源目录加载完成但未找到有效精灵帧');
                    console.error(error.message);
                    reject(error);
                }
            });
        });
    }
    /**
     * 生成地图
     * @param backgroundSprite 背景精灵帧
     */
    private generateMap(backgroundSprite: SpriteFrame): void {
        // 生成背景节点
        let bgNode = new Node('background');
        bgNode.parent = this.node;
        let bgSprite = bgNode.addComponent(Sprite);
        bgSprite.spriteFrame = backgroundSprite;
        bgNode.scale = new Vec3(1.1, 1.1 ,1);
        // 后续可以添加生成网格、初始植物等逻辑
        console.log('地图生成完成');
    }

    protected onDestroy(): void {
        MainManager._instance = null;
    }
}


